import 'package:core/core.dart';
import 'package:flutter/material.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';

import 'base_view_model.dart';

abstract class BaseViewModelList<T> extends BaseViewModel {
  static const int pageNumFirst = 1;
  final int pageSize = 20;
  int _currentPageNum = pageNumFirst;
  int get currentPageNum => _currentPageNum;
  List<T> data = [];

  @override
  void initState() {
    super.initState();
    if (autoLoadData) refresh();
  }

  @override
  void dispose() {
    refreshController.dispose();
    super.dispose();
  }

  void loadData({
    pageIndex,
    onSuccess,
    onCache,
    onError,
  });

  void _setData(List<T> data) {
    if (data.isEmpty) {
      this.data.clear();
      refreshController.refreshCompleted(resetFooterState: true);
      setEmpty();
    } else {
      this.data.clear();
      this.data.addAll(data);
      refreshController.refreshCompleted();
      if (data.length < pageSize) {
        refreshController.loadNoData();
      } else {
        refreshController.loadComplete();
      }
      setIdle();
    }
  }

  void _setMoreData(List<T> data) {
    if (data.isEmpty) {
      _currentPageNum--;
      refreshController.loadNoData();
      setEmpty();
    } else {
      this.data.addAll(data);
      // 小于分页的数量，禁止上拉加载更多
      if (data.length < pageSize) {
        refreshController.loadNoData();
      } else {
        refreshController.loadComplete();
      }
      setIdle();
    }
  }

  void refresh({
    ValueChanged<List<T>>? onSuccess,
    ValueChanged<List<T>>? onCache,
    ValueChanged<List<String>>? onError,
  }) async {
    setBusy();
    _currentPageNum = pageNumFirst;
    try {
      loadData(
        pageIndex: _currentPageNum,
        onSuccess: (data) {
          _setData(data);
          if (null != onSuccess) onSuccess(data);
        },
        onCache: (data) {
          if (null != onCache) {
            _setData(data);
            onCache(data);
          }
        },
        onError: (data) {
          refreshController.refreshFailed();
          if (null != onError) onError(data);
          setIdle();
        },
      );
    } catch (e) {
      refreshController.refreshFailed();
      setIdle();
    }
  }

  void loadMore({
    ValueChanged<List<T>>? onSuccess,
    ValueChanged<List<T>>? onCache,
    ValueChanged<List<String>>? onError,
  }) {
    setBusy();
    try {
      loadData(
        pageIndex: ++_currentPageNum,
        onSuccess: (data) {
          _setMoreData(data);
          if (null != onSuccess) onSuccess(data);
        },
        onCache: (data) {
          if (null != onCache) {
            _setMoreData(data);
            onCache(data);
          }
        },
        onError: (data) {
          _currentPageNum--;
          if (null != onError) onError(data);
          setIdle();
        },
      );
    } catch (e) {
      _currentPageNum--;
      setIdle();
    }
  }
}
